//
//  ZYTagView.swift
//  ZYUICommon
//
//  Created by Yi Zhou on 2025/1/8.
//

import Foundation
import UIKit

public protocol ZYTagViewDelegate: AnyObject {
    
    /// tag个数
    /// - Returns: description
    func tagViewNumberOfItem() -> Int
    
    /// tag的Item
    /// - Parameter index: index description
    /// - Returns: description
    func tagView(cellForRowAt index: Int) -> UIView
    
    /// tag的Item的size
    /// - Parameter index: index description
    /// - Returns: description
    func tagView(sizeForRowAt index: Int) -> CGSize
    
    /// tag的点击事件
    /// - Parameter index: index description
    func tagView(didSelectRowAt index: Int)
}

//MARK: - ZYTagView
public class ZYTagView: UIScrollView {
    
    /// 代理
    public weak var tDelegate: ZYTagViewDelegate?
    
    /// 最大宽度（如果不设置默认就是bounds宽）
    public var maxWidth: CGFloat = 0
    
    /// item之间的水平间距
    public var horizontalPadding: CGFloat = 10
    
    /// item之间的上下间距
    public var verticalPadding: CGFloat = 10
    
    /// 对齐方式
    public var alignment: ZYEnumTagAlignment = .left
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        maxWidth = self.bounds.width
        reloadData()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func reloadData() {
        switch alignment {
        case .left:
            setupSubviewsLeft()
        case .right:
            setupSubviewsRight()
        }
    }
    
    private func setupSubviewsLeft() {
        guard let delegate = tDelegate else { return }
        let number = delegate.tagViewNumberOfItem()
        guard number > 0 else { return }
        self.zyRemoveAllSubviews()
        
        var itemX: CGFloat = 0
        var itemY: CGFloat = 0
        var contentHeight: CGFloat = 0
        /// 每一行所包含的size（解决一行之间有不同高度的情况）
        var divSizeList: [CGSize] = []
        
        for index in 0..<number {
            
            let itemView = delegate.tagView(cellForRowAt: index)
            
            itemView.isUserInteractionEnabled = true
            
            let itemSize = delegate.tagView(sizeForRowAt: index)
            
            itemView.zyAddTapGesture { [weak self] in
                self?.tDelegate?.tagView(didSelectRowAt: index)
            }
            
            itemView.frame = CGRect(origin: CGPoint(x: itemX, y: itemY), size: itemSize)
            
            self.addSubview(itemView)
            
            itemX = itemX + itemSize.width + horizontalPadding
            
            var nextItemWidth: CGFloat = 0
            if index + 1 < number {
                let nextItemSize = delegate.tagView(sizeForRowAt: index + 1)
                nextItemWidth = nextItemSize.width
            }
            
            if maxWidth - itemX < nextItemWidth {
                itemX = 0
                let maxHeight = currentLineMaxHeight(divSizeList)
                itemY += maxHeight + verticalPadding
                contentHeight = itemY + maxHeight
                divSizeList.removeAll()
            }
            divSizeList.append(itemSize)
            
        }
        self.contentSize = CGSize(width: self.bounds.size.width, height: contentHeight)
    }
    
    private func setupSubviewsRight() {
        guard let delegate = tDelegate else { return }
        let number = delegate.tagViewNumberOfItem()
        guard number > 0 else { return }
        self.zyRemoveAllSubviews()
        
        let firstItemSize = delegate.tagView(sizeForRowAt: 0)
        var itemX: CGFloat = maxWidth - firstItemSize.width
        var itemY: CGFloat = 0
        var contentHeight: CGFloat = 0
        /// 每一行所包含的size
        var divSizeList: [CGSize] = []
        
        for index in 0..<number {
            let itemView = delegate.tagView(cellForRowAt: index)
            
            itemView.isUserInteractionEnabled = true
            
            let itemSize = delegate.tagView(sizeForRowAt: index)
            
            itemView.zyAddTapGesture { [weak self] in
                self?.tDelegate?.tagView(didSelectRowAt: index)
            }
            
            itemView.frame = CGRect(origin: CGPoint(x: itemX, y: itemY), size: itemSize)
            self.addSubview(itemView)
            
            var nextItemWidth: CGFloat = 0
            if index + 1 < number {
                let nextItemSize = delegate.tagView(sizeForRowAt: index + 1)
                nextItemWidth = nextItemSize.width
            }
            
            if itemX < nextItemWidth + verticalPadding {
                itemX = maxWidth - nextItemWidth
                let maxHeight = currentLineMaxHeight(divSizeList)
                itemY += maxHeight + verticalPadding
                contentHeight = itemY + maxHeight
                divSizeList.removeAll()
            } else {
                itemX = itemX - nextItemWidth - horizontalPadding
            }
            divSizeList.append(itemSize)
            
        }
        self.contentSize = CGSize(width: self.bounds.size.width, height: contentHeight)
    }
    
    /// 当前这一行最高的一个
    /// - Parameter tagSizeList: 当前这一行的所有size
    /// - Returns: 高度的最大值
    private func currentLineMaxHeight(_ tagSizeList: [CGSize]) -> CGFloat {
        return tagSizeList.max(by: { $0.height < $1.height })?.height ?? 0
    }
}
